package org.quipu.dto;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TransactionDto extends UniqueDto implements Cloneable {

    public enum Type {
        INCOME,
        OUTCOME,
        TRANSFER
    };

    private Date date = new Date();
    private boolean approved = true;
    private Long srcAccountId;
    private Long dstAccountId;
    private Double sum = 0.0;
    private Long currencyId;
    private Long convertCurrencyId;
    private Double convertCurrencyRate;
    private Long categoryId;
    private String description;
    private Map<Long, TagDto> tags = new HashMap<Long, TagDto>();

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public boolean isApproved() {
        return approved;
    }

    public void setApproved(boolean approved) {
        this.approved = approved;
    }

    public Long getCurrencyId() {
        return currencyId;
    }

    public void setCurrencyId(Long currencyId) {
        this.currencyId = currencyId;
    }

    public Double getSum() {
        return sum;
    }

    public void setSum(Double sum) {
        this.sum = sum;
    }

    public Long getConvertCurrencyId() {
        return convertCurrencyId;
    }

    public void setConvertCurrencyId(Long convertCurrencyId) {
        this.convertCurrencyId = convertCurrencyId;
    }

    public Double getConvertCurrencyRate() {
        return convertCurrencyRate;
    }

    public void setConvertCurrencyRate(Double convertCurrencyRate) {
        this.convertCurrencyRate = convertCurrencyRate;
    }

    public Double getConvertSum() {
        return sum * convertCurrencyRate;
    }

    public Long getSrcAccountId() {
        return srcAccountId;
    }

    public void setSrcAccountId(Long srcAccountId) {
        this.srcAccountId = srcAccountId;
    }

    public Long getDstAccountId() {
        return dstAccountId;
    }

    public void setDstAccountId(Long dstAccountId) {
        this.dstAccountId = dstAccountId;
    }

    public Long getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Long categoryId) {
        this.categoryId = categoryId;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Collection<TagDto> getTags() {
        return tags.values();
    }

    public TagDto getTags(Long tagId) {
        return tags.get(tagId);
    }

    public void addTag(TagDto tag) {
        tags.put(tag.getId(), tag);
    }

    public void addTags(Collection<TagDto> tags) {
        for(TagDto tag: tags) {
            this.tags.put(tag.getId(), tag);
        }
    }

    public void setTags(Collection<TagDto> tags) {
        removeAllTags();
        addTags(tags);
    }

    public boolean removeTag(Long tagId) {
        return tags.remove(tagId) != null;
    }

    public void removeAllTags() {
        tags.clear();
    }

    public Type getType() {
        if(srcAccountId != null) {
            if(dstAccountId != null) {
                return Type.TRANSFER;
            } else {
                return Type.OUTCOME;
            }
        } else {
            return Type.INCOME;
        }
    }

//    @Override
    public Object clone() {
        TransactionDto tr = new TransactionDto();
        tr.setId(getId());
        tr.setApproved(approved);
        tr.setCategoryId(categoryId);
        tr.setConvertCurrencyId(convertCurrencyId);
        tr.setConvertCurrencyRate(convertCurrencyRate);
        tr.setCurrencyId(currencyId);
        tr.setSum(sum);
        tr.setDate(date);
        tr.setSrcAccountId(srcAccountId);
        tr.setDstAccountId(dstAccountId);
        tr.setDescription(description);
        tr.addTags(getTags());
        return tr;
    }
}
